package com.gl.organigrama.json.dto;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import com.gl.organigrama.vos.Nodo;



public abstract class NodoDTOBuilder {
	
	public final static int OBJECTID_IDX = 0;
	public final static int PARENTID_IDX = 1;
	public final static int TOOLTIP_IDX = 2;
	public final static String EMPTY_FIELD = "";
	
	
	public static List<List<Object>>build(Nodo nodo){
		
		List<List<Object>>chartDTO = new ArrayList<List<Object>>();
		
		chartDTO.add(buildRootNode(nodo));
		
		
		if(nodo.hasInnerTree()){
			chartDTO.addAll(buildChildren(nodo.getInnerChildren(),String.valueOf(nodo.getId())));
		}
		return chartDTO;
	}
	
	private static Long generatedId = 10000L;
	private static Long nivelReal = 0L;
	private static Long n = 0L;

	private static Collection<? extends List<Object>> buildChildren(List<Nodo> children, String parentId) {
		
		List<List<Object>>childrenDTO = new ArrayList<List<Object>>();		
		
		for(Nodo child:children){
			
			n = n + 1;
			String id = parentId;
			Long level = child.getNivel();
			//construir nodos nulos si el hijo tiene un nivel mayor a uno.
			if(level > 1 && level != null)
			{

				for(int i=0; i<level-1;i++){
					Nodo nodo = new Nodo();
					nodo.setEstilo("Null");
					nodo.setSigla("");
					nodo.setCargo("");
					nodo.setFuncionario(null);
					nodo.setId( ++generatedId );
					childrenDTO.add(buildNode(nodo,id,nodo.getNivel()));
					id = String.valueOf(nodo.getId());
				}
				if(n>1){
					nivelReal = level+1;
				}else nivelReal = level;
				
			}else nivelReal = n;
			
			//fin nodo nulos
			
			//construir el nodo hijo
			childrenDTO.add(buildNode(child, id, nivelReal));
			
			if(child.hasChildren()){				
				childrenDTO.addAll(buildChildren(child.getHijosNivelUno(), String.valueOf(child.getId())));
			}
		}
		n = ((n - 1L)==-1)?0L:n-1L;
		return childrenDTO;
	}

	private static List<Object> buildRootNode(Nodo nodo) {
		
		return buildNode(nodo, EMPTY_FIELD, nodo.getNivel());
	}
	
	private static List<Object> buildNode(Nodo nodo, String parentId, Long nivel) {

		String moreinfo = "";
		if(nodo.getFuncionario() != null){
			String nombre = ((nodo.getFuncionario().getNombre())==null)?"-":nodo.getFuncionario().getNombre();
			String tel = ((nodo.getFuncionario().getTelefono())==null)?"-":nodo.getFuncionario().getTelefono();
			String mail = ((nodo.getFuncionario().getEmail())==null)?"-":nodo.getFuncionario().getEmail();
			moreinfo = nombre+","+tel+","+mail;
		}
		
		//setear el estilo segun el nivel del nodo
		if(nivel!= null){
				switch (nivel.intValue()) {
					case 0:
						nodo.setEstilo("Bordo");
						break;
					case 1:
						nodo.setEstilo("Pink");
						break;
					case 2:
						nodo.setEstilo("Yellow");
						break;
					case 3:
						nodo.setEstilo("Blue");
						break;
					case 4:
						nodo.setEstilo("Green");
						break;
					default:
						break;				
				}
		}
		
		List<Object> nodeDTO = new ArrayList<Object>();
		nodeDTO.add(buildObectID(nodo)); //ojectId = {v: , f:}
		nodeDTO.add(parentId); // array {v: , f:},parentId
		nodeDTO.add(parentId); // array {v: , f:},parentId,parentId
		nodeDTO.add(moreinfo); // array {v: , f:},parentId,parentId,moreinfo
		return nodeDTO; //nodeDTO = {v: , f:},parentId,parentId,moreinfo
	}

	private static Object buildObectID(Nodo nodo) { //se invoca el buildhtmlbody para armar el objeto del json
		
		return new ObjectID(nodo.getId(), buildHtmlBody(nodo));
	}

	private static String buildHtmlBody(Nodo nodo) {
		
		return HTMLBodyBuilder.build(nodo);
	}

	@XmlRootElement
	public static class ObjectID{
		
		@XmlElement(name="v")
		public String id;
		
		@XmlElement(name="f")
		public String htmlBody;
		
		public ObjectID(){}
		
		public ObjectID(Long id, String htmlBody){
			this.id = String.valueOf(id);
			this.htmlBody = htmlBody;
		}
	}

}
 